<section data-type="chapter" id="_chapter_2_forces">
  <h1>Chapter 2. Forces</h1>

  <blockquote data-type="epigraph">
    <p>“Don’t underestimate the Force.”</p>

    <p data-type="attribution">— Darth Vader</p>
  </blockquote>

  <a data-primary="forces" data-type="indexterm"></a>

  <p>
    In the final example of Chapter 1, we saw how we could calculate a dynamic
    acceleration based on a vector pointing from a circle on the screen to the
    mouse position. The resulting motion resembled a magnetic attraction between
    circle and mouse, as if some <em>force</em> were pulling the circle in
    towards the mouse. In this chapter we will formalize our understanding of
    the concept of a force and its relationship to acceleration. Our goal, by
    the end of this chapter, is to understand how to make multiple objects move
    around the screen and respond to a variety of environmental forces.
  </p>

  <section data-type="sect1" id="chapter02_section1">
    <h2>2.1 Forces and Newton’s Laws of Motion</h2>

    <a
      data-primary="forces"
      data-secondary="Newton's laws of motion"
      data-type="indexterm"
    ></a>
    <a data-primary="Newton" data-secondary="Isaac" data-type="indexterm"></a>

    <p>
      Before we begin examining the practical realities of simulating forces in
      code, let’s take a conceptual look at what it means to be a force in the
      real world. Just like the word “vector,” “force” is often used to mean a
      variety of things. It can indicate a powerful intensity, as in “She pushed
      the boulder with great force” or “He spoke forcefully.” The definition of
      <strong><em>force</em></strong> that we care about is much more formal and
      comes from Isaac Newton’s laws of motion:
    </p>

    <a data-primary="forces" data-secondary="defined" data-type="indexterm"></a>

    <p>
      <span class="highlight"
        >A force is a vector that causes an object with mass to
        accelerate.</span
      >
    </p>

    <p>
      The good news here is that we recognize the first part of the definition:
      <em>a force is a vector</em>. Thank goodness we just spent a whole chapter
      learning what a vector is and how to program with <code>p5.Vector</code
      ><code>s</code>!
    </p>

    <p>
      Let’s look at Newton’s three laws of motion in relation to the concept of
      a force.
    </p>

    <section data-type="sect2" id="_newton_s_first_law">
      <h3>Newton’s First Law</h3>

      <a data-primary="Newton's first law" data-type="indexterm"></a>

      <p>Newton’s first law is commonly stated as:</p>

      <p>
        <span class="highlight"
          >An object at rest stays at rest and an object in motion stays in
          motion.</span
        >
      </p>

      <p>
        However, this is missing an important element related to forces. We
        could expand it by stating:
      </p>

      <p>
        <span class="highlight"
          >An object at rest stays at rest and an object in motion stays in
          motion at a constant speed and direction unless acted upon by an
          unbalanced force.</span
        >
      </p>

      <a data-primary="Aristotle" data-type="indexterm"></a>

      <p>
        By the time Newton came along, the prevailing theory of
        motion—formulated by Aristotle—was nearly two thousand years old. It
        stated that if an object is moving, some sort of force is required to
        keep it moving. Unless that moving thing is being pushed or pulled, it
        will simply slow down or stop. Right?
      </p>

      <a data-primary="equilibrium" data-type="indexterm"></a>
      <a
        data-primary="forces"
        data-secondary="equilibrium"
        data-type="indexterm"
      ></a>
      <a
        data-primary="forces"
        data-secondary="terminal velocity"
        data-type="indexterm"
      ></a>
      <a data-primary="terminal velocity" data-type="indexterm"></a>

      <p>
        This, of course, is not true. In the absence of any forces, no force is
        required to keep an object moving. An object (such as a ball) tossed in
        the earth’s atmosphere slows down because of air resistance (a force).
        An object’s velocity will only remain constant in the absence of any
        forces or if the forces that act on it cancel each other out, i.e. the
        net force adds up to zero. This is often referred to as
        <strong><em>equilibrium</em></strong
        >. The falling ball will reach a terminal velocity (that stays constant)
        once the force of air resistance equals the force of gravity.
      </p>

      <figure id="chapter02_figure1">
        <img
          alt="Figure 2.1: The pendulum doesn't move because all the forces cancel each other out (add up to a net force of zero)."
          src="chapter02/ch02_01.png"
        />
        <figcaption>
          Figure 2.1: The pendulum doesn't move because all the forces cancel
          each other out (add up to a net force of zero).&nbsp;
        </figcaption>
      </figure>

      <p>
        In our p5 world, we could restate Newton’s first law as follows:
      </p>

      <a
        data-primary="Newton's first law"
        data-secondary="PVector class and"
        data-type="indexterm"
      ></a>
      <a
        data-primary="PVector class (Processing)"
        data-secondary="Newton's first law and"
        data-type="indexterm"
      ></a>

      <p>
        <span class="highlight"
          >An object’s p5.Vector velocity will remain constant if it is in a state
          of equilibrium.</span
        >
      </p>

      <p>
        Skipping Newton’s second law (arguably the most important law for our
        purposes) for a moment, let’s move on to the third law.
      </p>

      <a data-primary="Newton's third law" data-type="indexterm"></a>
    </section>

    <section data-type="sect2" id="_newton_s_third_law">
      <h3>Newton’s Third Law</h3>

      <p>This law is often stated as:</p>

      <p>
        <span class="highlight"
          >For every action there is an equal and opposite reaction.</span
        >
      </p>

      <p>
        This law frequently causes some confusion in the way that it is stated.
        For one, it sounds like one force causes another. Yes, if you push
        someone, that someone may <em>actively</em> decide to push you back. But
        this is not the action and reaction we are talking about with Newton’s
        third law.
      </p>

      <p>
        Let’s say you push against a wall. The wall doesn’t actively decide to
        push back on you. There is no “origin” force. Your push simply includes
        both forces, referred to as an “action/reaction pair.”
      </p>

      <p>A better way of stating the law might be:</p>

      <p>
        <span class="highlight"
          >Forces always occur in pairs. The two forces are of equal strength,
          but in opposite directions.</span
        >
      </p>

      <p>
        Now, this still causes confusion because it sounds like these forces
        would always cancel each other out. This is not the case. Remember, the
        forces act on different objects. And just because the two forces are
        equal, it doesn’t mean that the movements are equal (or that the objects
        will stop moving).
      </p>

      <p>
        Try pushing on a stationary truck. Although the truck is far more
        powerful than you, unlike a moving one, a stationary truck will never
        overpower you and send you flying backwards. The force you exert on it
        is equal and opposite to the force exerted on your hands. The outcome
        depends on a variety of other factors. If the truck is a small truck on
        an icy downhill, you’ll probably be able to get it to move. On the other
        hand, if it’s a very large truck on a dirt road and you push hard enough
        (maybe even take a running start), you could injure your hand.
      </p>

      <p>And if you are wearing roller skates when you push on that truck?</p>

      <figure id="chapter02_figure2">
        <img alt="Figure 2.2" src="chapter02/ch02_02.png" />
        <figcaption>Figure 2.2</figcaption>
      </figure>

      <p>
        You’ll accelerate away from the truck, sliding along the road while the
        truck stays put. Why do you slide but not the truck? For one, the truck
        has a much larger mass (which we’ll get into with Newton’s second law).
        There are other forces at work too, namely the friction of the truck’s
        tires and your roller skates against the road.
      </p>
    </section>

    <section
      data-type="sect2"
      id="_newton_s_third_law_as_seen_through_the_eyes_of_processing"
    >
      <h3>Newton’s Third Law (as seen through the eyes of p5)</h3>

      <a
        data-primary="Newton's third law"
        data-secondary="PVector class and"
        data-type="indexterm"
      ></a>
      <a
        data-primary="PVector class (Processing)"
        data-secondary="Newton's third law and"
        data-type="indexterm"
      ></a>

      <p>
        <span class="highlight"
          >If we calculate a p5.Vector f that is a force of object A on object B,
          we must also apply the force—p5.Vector.mult(f,-1);—that B exerts on
          object A.</span
        >
      </p>

      <p>
        We’ll see that in the world of p5 programming, we don’t always
        have to stay true to the above. Sometimes, such as in the case of
        <a href="#chapter02_example6">gravitational attraction between bodies</a
        >, we’ll want to model equal and opposite forces. Other times, such as
        when we’re simply saying, “Hey, there’s some wind in the environment,”
        we’re not going to bother to model the force that a body exerts back on
        the air. In fact, we’re not modeling the air at all! Remember, we are
        simply taking inspiration from the physics of the natural world, not
        simulating everything with perfect precision.
      </p>
    </section>
  </section>

  <section data-type="sect1" id="chapter02_section2">
    <h2>2.2 Forces and p5—Newton’s Second Law as a Function</h2>

    <a
      data-primary="acceleration"
      data-secondary="Newton's second law"
      data-type="indexterm"
    ></a>
    <a
      data-primary="natural phenomena"
      data-secondary="Newton's second law"
      data-tertiary="modeling"
      data-type="indexterm"
    ></a>
    <a data-primary="Newton's second law" data-type="indexterm"></a>

    <p>
      And here we are at the most important law for the p5 programmer.
    </p>

    <section data-type="sect2" id="_newton_s_second_law">
      <h3>Newton’s Second Law</h3>

      <p>This law is stated as:</p>

      <p>
        <span class="highlight">Force equals mass times acceleration.</span>
      </p>

      <p>Or:</p>

      <div data-type="equation">\vec{F} = M \times \vec{A}</div>

      <p>
        Why is this the most important law for us? Well, let’s write it a
        different way.
      </p>

      <div data-type="equation">\vec{A} = \vec{F} / M</div>

      <p>
        Acceleration is directly proportional to force and inversely
        proportional to mass. This means that if you get pushed, the harder you
        are pushed, the faster you’ll move (accelerate). The bigger you are, the
        slower you’ll move.
      </p>

      <a data-primary="density" data-type="indexterm"></a>
      <a
        data-primary="mass"
        data-secondary="weight vs."
        data-type="indexterm"
      ></a>
      <a
        data-primary="weight"
        data-secondary="mass vs."
        data-type="indexterm"
      ></a>

      <div data-type="note">
        <h2>Weight vs. Mass</h2>

        <ul>
          <li>
            <p>
              The <strong><em>mass</em></strong> of an object is a measure of
              the amount of matter in the object (measured in kilograms).
            </p>
          </li>
          <li>
            <p>
              <strong><em>Weight</em></strong
              >, though often mistaken for mass, is technically the force of
              gravity on an object. From Newton’s second law, we can calculate
              it as mass times the acceleration of gravity (<code>w</code> =
              <code>m</code> * <code>g</code>). Weight is measured in newtons.
            </p>
          </li>
          <li>
            <p>
              <strong><em>Density</em></strong> is defined as the amount of mass
              per unit of volume (grams per cubic centimeter, for example).
            </p>
          </li>
        </ul>

        <p>
          Note that an object that has a mass of one kilogram on earth would
          have a mass of one kilogram on the moon. However, it would weigh only
          one-sixth as much.
        </p>
      </div>

      <p>
        Now, in the world of p5, what is mass anyway? Aren’t we dealing
        with pixels? To start in a simpler place, let’s say that in our pretend
        pixel world, all of our objects have a mass equal to 1. <code>F</code>/
        1 = <code>F</code>. And so:
      </p>

      <div data-type="equation">\vec{A} = \vec{F}</div>

      <p>
        The acceleration of an object is equal to force. This is great news.
        After all, we saw in Chapter 1 that acceleration was the key to
        controlling the movement of our objects on screen. position is adjusted
        by velocity, and velocity by acceleration. Acceleration was where it all
        began. Now we learn that <em>force</em> is truly where it all begins.
      </p>

      <p>
        Let’s take our <code>Mover</code> class, with position, velocity, and
        acceleration.
      </p>

      <pre
        data-code-language="javascript"
        data-type="programlisting"
        class="codesplit"
      >
class Mover {
  constructor(){
    this.position = createVector();
    this.velocity = createVector();
    this.acceleration = createVector();
  }
}</pre
      >

      <p>
        Now our goal is to be able to add forces to this object, perhaps saying:
      </p>

      <pre
        data-code-language="javascript"
        data-type="programlisting"
        class="codesplit"
      >
mover.applyForce(wind);</pre
      >

      <p>or:</p>

      <pre
        data-code-language="javascript"
        data-type="programlisting"
        class="codesplit"
      >
mover.applyForce(gravity);</pre
      >

      <p>
        where wind and gravity are <code>p5.Vector</code> objects. According to
        Newton’s second law, we could implement this function as follows.
      </p>

      <pre
        data-code-language="javascript"
        data-type="programlisting"
        class="codesplit"
      >
applyForce(force) {
  //{!1} Newton's second law at its simplest.
  this.acceleration = force;
}</pre
      >
    </section>
  </section>

  <section data-type="sect1" id="chapter02_section3">
    <h2>2.3 Force Accumulation</h2>

    <a
      data-primary="forces"
      data-secondary="accumulation of"
      data-type="indexterm"
    ></a>

    <p>
      This looks pretty good. After all, <em>acceleration = force</em> is a
      literal translation of Newton’s second law (without mass). Nevertheless,
      there’s a pretty big problem here. Let’s return to what we are trying to
      accomplish: creating a moving object on the screen that responds to wind
      and gravity.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
mover.applyForce(wind);
mover.applyForce(gravity);
mover.update();
mover.display();</pre
    >

    <p>
      OK, let’s <em>be</em> the computer for a moment. First, we call
      <code>applyForce()</code> with wind. And so the
      <code>Mover</code> object’s acceleration is now assigned the
      <code>PVector</code> <code>wind</code>. Second, we call
      <code>applyForce()</code> with gravity. Now the
      <code>Mover</code> object’s acceleration is set to the gravity
      <code>PVector</code>. Third, we call <code>update()</code>. What happens
      in <code>update()</code>? Acceleration is added to velocity.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
this.velocity.add(this.acceleration);</pre
    >

    <p>
      We’re not going to see any error in p5, but zoinks! We’ve got a
      major problem. What is the value of acceleration when it is added to
      velocity? It is equal to the gravity force. Wind has been left out! If we
      call <code>applyForce()</code> more than once, it overrides each previous
      call. How are we going to handle more than one force?
    </p>

    <a data-primary="force accumulation" data-type="indexterm"></a>

    <p>
      The truth of the matter here is that we started with a simplified
      statement of Newton’s second law. Here’s a more accurate way to put it:
    </p>

    <p>
      <span class="highlight">Net Force equals mass times acceleration.</span>
    </p>

    <p>
      Or, acceleration is equal to the <em>sum of all forces</em> divided by
      mass. This makes perfect sense. After all, as we saw in Newton’s first
      law, if all the forces add up to zero, an object experiences an
      equilibrium state (i.e. no acceleration). Our implementation of this is
      through a process known as <strong><em>force accumulation</em></strong
      >. It’s actually very simple; all we need to do is add all of the forces
      together. At any given moment, there might be 1, 2, 6, 12, or 303 forces.
      As long as our object knows how to accumulate them, it doesn’t matter how
      many forces act on it.
    </p>

    <pre data-code-language="java" data-type="programlisting" class="codesplit">
applyForce(force) {
  //{!1} Newton's second law, but with force accumulation. We now add each force to acceleration, one at a time.
  this.acceleration.add(force);
}</pre
    >

    <p>
      Now, we’re not finished just yet. Force accumulation has one more piece.
      Since we’re adding all the forces together at any given moment, we have to
      make sure that we clear acceleration (i.e. set it to zero) before each
      time <code>update()</code> is called. Let’s think about wind for a moment.
      Sometimes the wind is very strong, sometimes it’s weak, and sometimes
      there’s no wind at all. At any given moment, there might be a huge gust of
      wind, say, when the user holds down the mouse.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
if (mousePressed) {
  const wind = createVector(0.5, 0);
  mover.applyForce(wind);
}</pre
    >

    <a
      data-primary="acceleration"
      data-secondary="force accumulation and"
      data-type="indexterm"
    ></a>

    <p>
      When the user releases the mouse, the wind will stop, and according to
      Newton’s first law, the object will continue to move at a constant
      velocity. However, if we had forgotten to reset acceleration to zero, the
      gust of wind would still be in effect. Even worse, it would add onto
      itself from the previous frame, since we are accumulating forces!
      Acceleration, in our simulation, has no memory; it is simply calculated
      based on the environmental forces present at a moment in time. This is
      different than, say, position, which must remember where the object was in
      the previous frame in order to move properly to the next.
    </p>

    <p>
      The easiest way to implement clearing the acceleration for each frame is
      to multiply the <code>PVector</code> by 0 at the end of
      <code>update()</code>.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
update() {
  this.velocity.add(this.acceleration);
  this.position.add(this.velocity);
  this.acceleration.mult(0);
}</pre
    >

    <div data-type="exercise" id="chapter02_exercise1">
      <h5>Exercise 2.1</h5>

      <p>
        Using forces, simulate a helium-filled balloon floating upward and
        bouncing off the top of a window. Can you add a wind force that changes
        over time, perhaps according to Perlin noise?
      </p>
    </div>
  </section>

  <section data-type="sect1" id="chapter02_section4">
    <h2>2.4 Dealing with Mass</h2>

    <a data-primary="mass" data-secondary="modeling" data-type="indexterm"></a>
    <a
      data-primary="natural phenomena"
      data-secondary="mass"
      data-tertiary="modeling"
      data-type="indexterm"
    ></a>

    <p>
      OK. We’ve got one tiny little addition to make before we are done with
      integrating forces into our <code>Mover</code> class and are ready to look
      at examples. After all, Newton’s second law is really
      <span data-type="equation">\vec{F} = M \times \vec{A}</span>, not
      <span data-type="equation">\vec{F} = \vec{A}</span>. Incorporating mass is
      as easy as adding an instance variable to our class, but we need to spend
      a little more time here because a slight complication will emerge.
    </p>

    <p>First we just need to add mass.</p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
class Mover {
  constructor(){
    this.position = createVector();
    this.velocity = createVector();
    this.acceleration = createVector();
    //{!1} Adding mass as a float
    this.mass = ????;
  }
}</pre
    >

    <a
      data-primary="mass"
      data-secondary="units of measurement"
      data-tertiary="defining"
      data-type="indexterm"
    ></a>

    <div data-type="note">
      <h2>Units of Measurement</h2>

      <p>
        Now that we are introducing mass, it’s important to make a quick note
        about units of measurement. In the real world, things are measured in
        specific units. We say that two objects are 3 meters apart, the baseball
        is moving at a rate of 90 miles per hour, or this bowling ball has a
        mass of 6 kilograms. As we’ll see later in this book, sometimes we will
        want to take real-world units into consideration. However, in this
        chapter, we’re going to ignore them for the most part. Our units of
        measurement are in pixels (“These two circles are 100 pixels apart”) and
        frames of animation (“This circle is moving at a rate of 2 pixels per
        frame”). In the case of mass, there isn’t any unit of measurement for us
        to use. We’re just going to make something up. In this example, we’re
        arbitrarily picking the number 10. There is no unit of measurement,
        though you might enjoy inventing a unit of your own, like “1 moog” or “1
        yurkle.” It should also be noted that, for demonstration purposes, we’ll
        tie mass to pixels (drawing, say, a circle with a radius of 10). This
        will allow us to visualize the mass of an object. In the real world,
        however, size does not definitely indicate mass. A small metal ball
        could have a much higher mass than a large balloon due to its higher
        density.
      </p>
    </div>

    <p>
      Mass is a scalar (float), not a vector, as it’s just one number describing
      the amount of matter in an object. We could be fancy about things and
      compute the area of a shape as its mass, but it’s simpler to begin by
      saying, “Hey, the mass of this object is…um, I dunno…how about 10?”
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
constructor() {
  this.position = createVector(random(width), random(height));
  this.velocity = createVector(0, 0);
  this.acceleration = createVector(0, 0);
  this.mass = 10.0;
}</pre
    >

    <a
      data-primary="forces"
      data-secondary="applying to objects"
      data-type="indexterm"
    ></a>

    <p>
      This isn’t so great since things only become interesting once we have
      objects with varying mass, but it’ll get us started. Where does mass come
      in? We use it while applying Newton’s second law to our object.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
applyForce(force) {
  //{!2} Newton's second law (with force accumulation and mass)
  force.div(mass);
  this.acceleration.add(force);
}</pre
    >

    <p>
      Yet again, even though our code looks quite reasonable, we have a fairly
      major problem here. Consider the following scenario with two
      <code>Mover</code> objects, both being blown away by a wind force.
    </p>

    <pre data-code-language="java" data-type="programlisting" class="codesplit">
Mover m1 = new Mover();
Mover m2 = new Mover();

PVector wind = new PVector(1,0);

m1.applyForce(wind);
m2.applyForce(wind);</pre
    >

    <p>
      Again, let’s <em>be</em> the computer. Object <code>m1</code> receives the
      wind force—(1,0)—divides it by mass (10), and adds it to acceleration.
    </p>

    <p>
      <span class="formula">m1 equals wind force: &nbsp;&nbsp;&nbsp; (1,0)</span
      ><br />
      <span class="formula">Divided by mass of 10: &nbsp;&nbsp; (0.1,0)</span>
    </p>

    <a
      data-primary="object-oriented programming"
      data-secondary="references to vs. copies of objects"
      data-type="indexterm"
    ></a>

    <p>
      OK. Moving on to object <code>m2</code>. It also receives the wind
      force—(1,0). Wait. Hold on a second. What is the value of the wind force?
      Taking a closer look, the wind force is actually now—(0.1,0)!! Do you
      remember this little tidbit about working with objects? When you pass an
      object (in this case a <code>PVector</code>) into a function, you are
      passing a reference to that object. It’s not a copy! So if a function
      makes a change to that object (which, in this case, it does by dividing by
      mass) then that object is permanently changed! But we don’t want
      <code>m2</code> to receive a force divided by the mass of object
      <code>m1</code>. We want it to receive that force in its original
      state—(1,0). And so we must protect ourselves and make a copy of the
      <code>PVector</code> f before dividing it by mass. Fortunately, the
      <code>PVector</code> class has a convenient method for making a
      copy—<code>copy()</code>. <code>copy()</code> returns a new
      <code>PVector</code> object with the same data. And so we can revise
      <code>applyForce()</code> as follows:
    </p>

    <pre data-code-language="java" data-type="programlisting" class="codesplit">
applyForce(force) {
  //{!1} Making a copy of the PVector before using it!
  const f = force.copy();
  f.div(this.mass);
  this.acceleration.add(f);
}</pre
    >

    <p>
      There’s another way we could write the above function, using the static
      method <code>div()</code>. For help with this exercise, review static
      methods in <a href="#chapter01_section9">Chapter 1</a>.
    </p>

    <div data-type="exercise" id="chapter02_exercise2">
      <h5>Exercise 2.2</h5>

      <p>
        Rewrite the <code>applyForce()</code> method using the static method
        <code>div()</code> instead of <code>copy()</code>.
      </p>

      <pre
        data-code-language="java"
        data-type="programlisting"
        class="codesplit"
      >
applyForce(force) {
  const f = _______.___(_____,____);
  this.acceleration.add(f);
}</pre
      >
    </div>
  </section>

  <section data-type="sect1" id="chapter02_section5">
    <h2>2.5 Creating Forces</h2>

    <a
      data-primary="forces"
      data-secondary="creating"
      data-type="indexterm"
    ></a>

    <p>
      Let’s take a moment to remind ourselves where we are. We know what a force
      is (a vector), and we know how to apply a force to an object (divide it by
      mass and add it to the object’s acceleration vector). What are we missing?
      Well, we have yet to figure out how we get a force in the first place.
      Where do forces come from?
    </p>

    <p>
      In this chapter, we’ll look at two methods for creating forces in our
      p5 world.
    </p>

    <a
      data-primary="natural phenomena"
      data-secondary="forces"
      data-tertiary="modeling"
      data-type="indexterm"
    ></a>

    <ol>
      <li>
        <p>
          <strong>Make up a force!</strong> After all, you are the programmer,
          the creator of your world. There’s no reason why you can’t just make
          up a force and apply it.
        </p>
      </li>
      <li>
        <p>
          <strong>Model a force!</strong> Yes, forces exist in the real world.
          And physics textbooks often contain formulas for these forces. We can
          take these formulas, translate them into source code, and model
          real-world forces in p5.
        </p>
      </li>
    </ol>

    <p>
      The easiest way to make up a force is to just pick a number. Let’s start
      with the idea of simulating wind. How about a wind force that points to
      the right and is fairly weak? Assuming a <code>Mover</code> object m, our
      code would look like:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const wind = createVector(0.01,0);
m.applyForce(wind);</pre
    >

    <p>
      The result isn’t terribly interesting, but it is a good place to start. We
      create a <code>p5.Vector</code> object, initialize it, and pass it into an
      object (which in turn will apply it to its own acceleration). If we wanted
      to have two forces, perhaps wind and gravity (a bit stronger, pointing
      down), we might write the following:
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/B13QnJZul"
    >
      <img alt="ch02 ex01" src="chapter02/ch02_ex01.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 2.1: Forces</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const wind = createVector(0.01, 0);
const gravity = createVector(0, 0.1);
m.applyForce(wind);
m.applyForce(gravity);</pre
    >

    <p>
      Now we have two forces, pointing in different directions with different
      magnitudes, both applied to object <code>m</code>. We’re beginning to get
      somewhere. We’ve now built a world for our objects in p5, an
      environment to which they can actually respond.
    </p>

    <p>
      Let’s look at how we could make this example a bit more exciting with many
      objects of varying mass. To do this, we’ll need a quick review of
      object-oriented programming. Again, we’re not covering all the basics of
      programming here (for that you can check out any of the intro p5
      books listed in the introduction). However, since the idea of creating a
      world filled with objects is pretty fundamental to all the examples in
      this book, it’s worth taking a moment to walk through the steps of going
      from one object to many.
    </p>

    <p>
      This is where we are with the <code>Mover</code> class as a whole. Notice
      how it is identical to the <code>Mover</code> class created in Chapter 1,
      with two additions—<code>mass</code> and a new
      <code>applyForce()</code> function.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
class Mover {

  constructor() {
    //{!1} And for now, we'll just set the mass equal to 1 for simplicity.
    this.mass = 1;
    this.position = createVector(30, 30);
    this.velocity = createVector(0, 0);
    this.acceleration = createVector(0, 0);
  }

  // Newton's second law.
  applyForce(force) {
    //{!2} Receive a force, divide by mass, and add to acceleration.
    const f = PVector.div(force,this.mass);
    this.acceleration.add(f);
  }

  update() {
    //{!2} Motion 101 from Chapter 1
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);

    // Now add clearing the acceleration each time!
    this.acceleration.mult(0);
  }

  display() {
    stroke(0);
    fill(175);
    //{!1} Scaling the size according to mass.
    ellipse(this.position.x, this.position.y, this.mass*16, this.mass*16);
  }

  // Somewhat arbitrarily, we are deciding that an object bounces when it hits the edges of a window.
  checkEdges() {
    if (this.position.x > width) {
      this.position.x = width;
      this.velocity.x *= -1;
    } else if (this.position.x < 0) {
      this.velocity.x *= -1;
      this.position.x = 0;
    }

    if (this.position.y > height) {
      //{!2} Even though we said we shouldn't touch position and velocity directly, there are some exceptions. Here we are doing so as a quick and easy way to reverse the direction of our object when it reaches the edge.
      this.velocity.y *= -1;
      this.position.y = height;
    }
  }
}</pre
    >

    <p>
      Now that our class is set, we can choose to create, say, one hundred
      <code>Mover</code> objects with an array.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const movers = [];</pre
    >

    <p>
      And then we can initialize all of those <code>Mover</code> objects in
      <code>setup()</code> with a loop.
    </p>

    <pre data-code-language="java" data-type="programlisting" class="codesplit">
function setup() {
  for (let i = 0; i < movers.length; i++) {
    movers[i] = new Mover();
  }
}</pre
    >

    <p>
      But now we have a small issue. If we refer back to the
      <code>Mover</code> object’s constructor…
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
  constructor() {
    //{!2} Every object has a mass of 1 and a position of (30, 30).
    this.mass = 1;
    this.position = createVector(30, 30);
    this.velocity = createVector(0, 0);
    this.acceleration = createVector(0, 0);
  }</pre
    >

    <a
      data-primary="constructor"
      data-secondary="arguments"
      data-tertiary="adding to"
      data-type="indexterm"
    ></a>

    <p>
      …we discover that every <code>Mover</code> object is made exactly the same
      way. What we want are <code>Mover</code> objects of varying mass that
      start at varying positions. Here is where we need to increase the
      sophistication of our constructor by adding arguments.
    </p>

    <pre data-code-language="java" data-type="programlisting" class="codesplit">
  Mover(m, x, y) {
    //{!2} Now setting these variables with arguments
    this.mass = m;
    this.position = createVector(x, y);
    this.velocity = createVector(0, 0);
    this.acceleration = createVector(0, 0);
  }</pre
    >

    <p>
      Notice how the mass and position are no longer set to hardcoded numbers,
      but rather initialized via arguments passed through the constructor. This
      means we can create a variety of <code>Mover</code> objects: big ones,
      small ones, ones that start on the left side of the screen, ones that
      start on the right, etc.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
// A big Mover on the left side of the window
const m1 = new Mover(10, 0, height/2);
// A small Mover on the right side of the window
const m1 = new Mover(0.1, width, height/2);</pre
    >

    <p>
      With an array, however, we want to initialize all of the objects with a
      loop.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
function setup() {
  for (let i = 0; i < 10; i++) {
    // Initializing many Mover objects, all with random mass (and all starting at 0,0)
    movers[i] = new Mover(random(0.1, 5), i * 20, 0);
  }
}</pre
    >

    <p>
      For each mover created, the mass is set to a random value between 0.1 and
      5, the starting x-position is set to 0, and the starting y-position is set
      to 0. Certainly, there are all sorts of ways we might choose to initialize
      the objects; this is just a demonstration of one possibility.
    </p>

    <p>
      Once the array of objects is declared, created, and initialized, the rest
      of the code is simple. We run through every object, hand them each the
      forces in the environment, and enjoy the show.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/SJC2hk-dl"
    >
      <img alt="ch02 ex02" src="chapter02/ch02_ex02.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 2.2: Forces acting on many objects</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
function draw() {
  background(255);

  const wind = createVector(0.01,0);
  //{!1} Make up two forces.
  const gravity = createVector(0,0.1);

  //{!3} Loop through all objects and apply both forces to each object.
  for (let i = 0; i < movers.length; i++) {
    movers[i].applyForce(wind);
    movers[i].applyForce(gravity);
    movers[i].update();
    movers[i].display();
    movers[i].checkEdges();
  }
}</pre
    >

    <p>
      Note how in the above image, the smaller circles reach the right of the
      window faster than the larger ones. This is because of our formula:
      <em>acceleration = force divided by mass</em>. The larger the mass, the
      smaller the acceleration.
    </p>

    <div data-type="exercise" id="chapter02_exercise3">
      <h5>Exercise 2.3</h5>

      <p>
        Instead of objects bouncing off the edge of the wall, create an example
        in which an invisible force pushes back on the objects to keep them in
        the window. Can you weight the force according to how far the object is
        from an edge—i.e., the closer it is, the stronger the force?
      </p>
    </div>
  </section>

  <section data-type="sect1" id="chapter02_section6">
    <h2>2.6 Gravity on Earth and Modeling a Force</h2>

    <a
      data-primary="forces"
      data-secondary="gravity"
      data-tertiary="modeling"
      data-type="indexterm"
    ></a>
    <a data-primary="Galileo" data-type="indexterm"></a>
    <a
      data-primary="natural phenomena"
      data-secondary="gravity"
      data-type="indexterm"
    ></a>

    <p>
      You may have noticed something woefully inaccurate about this last
      example. The smaller the circle, the faster it falls. There is a logic to
      this; after all, we just stated (according to Newton’s second law) that
      the smaller the mass, the higher the acceleration. But this is not what
      happens in the real world. If you were to climb to the top of the Leaning
      Tower of Pisa and drop two balls of different masses, which one will hit
      the ground first? According to legend, Galileo performed this exact test
      in 1589, discovering that they fell with the same acceleration, hitting
      the ground at the same time. Why is this? As we will see later in this
      chapter, the force of gravity is calculated relative to an object’s mass.
      The bigger the object, the stronger the force. So if the force is scaled
      according to mass, it is canceled out when acceleration is divided by
      mass. We can implement this in our sketch rather easily by multiplying our
      made-up gravity force by mass.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/HyQea1W_l"
    >
      <img alt="ch02 ex03" src="chapter02/ch02_ex03.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 2.3: Gravity scaled by mass</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
for (let i = 0; i < movers.length; i++) {

    const wind = createVector(0.001,0);
    const m = movers[i].mass;
    //{!1} Scaling gravity by mass to be more accurate
    const gravity = createVector(0, 0.1*m);
    movers[i].applyForce(wind);
    movers[i].applyForce(gravity);

    movers[i].update();
    movers[i].display();
    movers[i].checkEdges();
  }</pre
    >

    <p>
      While the objects now fall at the same rate, because the strength of the
      wind force is independent of mass, the smaller objects still accelerate to
      the right more quickly.
    </p>

    <p>
      Making up forces will actually get us quite far. The world of p5
      is an orchestra of pixels and you are its conductor. So whatever you deem
      appropriate to be a force, well by golly, that’s the force it should be.
      Nevertheless, there may come a time where you find yourself wondering:
      “But how does it really all work?”
    </p>

    <a
      data-primary="forces"
      data-secondary="models of"
      data-tertiary="building"
      data-type="indexterm"
    ></a>
    <a
      data-primary="natural phenomena"
      data-secondary="physics (real world)"
      data-tertiary="modeling"
      data-type="indexterm"
    ></a>
    <a
      data-primary="physics"
      data-secondary="modeling"
      data-type="indexterm"
    ></a>

    <p>
      Open up any high school physics textbook and you will find some diagrams
      and formulas describing many different forces—gravity, electromagnetism,
      friction, tension, elasticity, and more. In this chapter we’re going to
      look at two forces—friction and gravity. The point we’re making here is
      not that friction and gravity are fundamental forces that you always need
      to have in your p5 sketches. Rather, we want to evaluate these two
      forces as case studies for the following process:
    </p>

    <ul>
      <li>
        <p>Understanding the concept behind a force</p>
      </li>
      <li>
        <p>Deconstructing the force’s formula into two parts:</p>

        <ul>
          <li>
            <p>How do we compute the force’s direction?</p>
          </li>
          <li>
            <p>How do we compute the force’s magnitude?</p>
          </li>
        </ul>
      </li>
      <li>
        <p>
          Translating that formula into p5 code that calculates a
          <code>p5.Vector</code> to be sent through our <code>Mover</code
          ><code>'s</code> <code>applyForce()</code> function
        </p>
      </li>
    </ul>

    <p>
      If we can follow the above steps with two forces, then hopefully if you
      ever find yourself Googling “atomic nuclei weak nuclear force” at 3 a.m.,
      you will have the skills to take what you find and adapt it for
      p5.
    </p>

    <a
      data-primary="formulae"
      data-secondary="evaluating in code"
      data-type="indexterm"
    ></a>

    <div data-type="note">
      <h2>Dealing with formulae</h2>

      <p>
        OK, in a moment we’re going to write out the formula for friction. This
        isn’t the first time we’ve seen a formula in this book; we just finished
        up our discussion of Newton’s second law,
        <span data-type="equation">\vec{F} = M \times \vec{A}</span> (or force =
        mass * acceleration). We didn’t spend a lot of time worrying about this
        formula because it’s a nice and simple one. Nevertheless, it’s a scary
        world out there. Just take a look at the equation for a “normal”
        distribution, which we covered (without looking at the formula) in the
        <a href="#intro_section4">Introduction</a>.
      </p>

      <div class="equation-w-sqrt-small">
        <div data-type="equation">
          \frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{(x-\mu)^2}{2\sigma^2}}
        </div>
      </div>

      <a
        data-primary="friction"
        data-secondary="formula for"
        data-type="indexterm"
      ></a>

      <p>
        What we’re seeing here is that formulas like to use a lot of symbols
        (quite often letters from the Greek alphabet). Let’s take a look at the
        formula for friction.
      </p>

      <div data-type="equation">\vec{friction} = -\mu * N * \hat{\nu}</div>

      <p>
        If it’s been a while since you’ve looked at a formula from a math or
        physics textbook, there are three key points that are important to cover
        before we move on.
      </p>

      <ul>
        <li>
          <p>
            <strong
              ><em
                >Evaluate the right side, assign to the left side.</em
              ></strong
            >
            This is just like in code! What we’re doing here is evaluating the
            right side of the equation and assigning it to the left. In the case
            above, we want to calculate the force of friction—the left side
            tells us what we want to calculate and the right side tells us how
            to do it.
          </p>
        </li>
        <li>
          <p>
            <strong><em>Are we talking about a vector or a scalar?</em></strong>
            It’s important for us to realize that in some cases, we’ll be
            looking at a vector; in others, a scalar. For example, in this case
            the force of friction is a vector. We can see that by the arrow
            above the word “friction.” It has a magnitude and direction. The
            right side of the equation also has a vector, as indicated by the
            symbol {unitv}, which in this case stands for the velocity unit
            vector.
          </p>
        </li>
        <li>
          <p>
            <strong
              ><em
                >When symbols are placed next to each other, we mean for them to
                be multiplied.</em
              ></strong
            >
            The formula above actually has four elements: -1, <em>&mu;</em>,
            <em>N</em>, and <span data-type="equation">\hat{v}</span> . We want
            to multiply them together and read the formula as:
            <span data-type="equation"
              >\vec{friction} = -1 * \mu * N * \hat{\nu}</span
            >
          </p>
        </li>
      </ul>
    </div>
  </section>

  <section data-type="sect1" id="chapter02_section7">
    <h2>2.7 Friction</h2>

    <a
      data-primary="forces"
      data-secondary="friction"
      data-tertiary="modeling"
      data-type="indexterm"
    ></a>
    <a
      data-primary="friction"
      data-secondary="modeling with formulae"
      data-type="indexterm"
    ></a>
    <a
      data-primary="natural phenomena"
      data-secondary="friction"
      data-type="indexterm"
    ></a>

    <p>Let’s begin with friction and follow our steps.</p>

    <a data-primary="dissipative force" data-type="indexterm"></a>

    <p>
      Friction is a <strong><em>dissipative force</em></strong
      >. A dissipative force is one in which the total energy of a system
      decreases when an object is in motion. Let’s say you are driving a car.
      When you press your foot down on the brake pedal, the car’s brakes use
      friction to slow down the motion of the tires. Kinetic energy (motion) is
      converted into thermal energy (heat). Whenever two surfaces come into
      contact, they experience friction. A complete model of friction would
      include separate cases for static friction (a body at rest against a
      surface) and kinetic friction (a body in motion against a surface), but
      for our purposes, we are only going to look at the kinetic case.
    </p>

    <p>Here’s the formula for friction:</p>

    <figure id="chapter02_figure3">
      <img alt="Figure 2.3" src="chapter02/ch02_03.png" />
      <figcaption>Figure 2.3</figcaption>
    </figure>

    <a
      data-primary="friction"
      data-secondary="determining direction/magnitude of"
      data-type="indexterm"
    ></a>

    <p>
      It’s now up to us to separate this formula into two components that
      determine the direction of friction as well as the magnitude. Based on the
      diagram above, we can see that
      <em>friction points in the opposite direction of velocity.</em> In fact,
      that’s the part of the formula that says -1 *
      <span data-type="equation">\hat{v}</span>, or -1 times the velocity unit
      vector. In p5, this would mean taking the velocity vector,
      normalizing it, and multiplying by -1.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const friction = this.velocity.copy();
friction.normalize();
// Let’s figure out the direction of the friction force
// (a unit vector in the opposite direction of velocity).
friction.mult(-1);</pre
    >

    <p>
      Notice two additional steps here. First, it’s important to make a copy of
      the velocity vector, as we don’t want to reverse the object’s direction by
      accident. Second, we normalize the vector. This is because the magnitude
      of friction is not associated with how fast it is moving, and we want to
      start with a friction vector of magnitude 1 so that it can easily be
      scaled.
    </p>

    <a data-primary="mu (μ)" data-type="indexterm"></a>
    <a data-primary="coefficient of friction" data-type="indexterm"></a>
    <a
      data-primary="coefficient of friction"
      data-secondary="mu (μ)"
      data-type="indexterm"
    ></a>
    <a
      data-primary="friction"
      data-secondary="mu (μ)"
      data-type="indexterm"
    ></a>
    <a
      data-primary="friction"
      data-secondary="coefficient of friction"
      data-type="indexterm"
    ></a>

    <p>
      According to the formula, the magnitude is <code>&mu;</code> *
      <code>N</code>. <code>&mu;</code>, the Greek letter
      <em>mu</em> (pronounced “mew”), is used here to describe the
      <strong><em>coefficient of friction</em></strong
      >. The coefficient of friction establishes the strength of a friction
      force for a particular surface. The higher it is, the stronger the
      friction; the lower, the weaker. A block of ice, for example, will have a
      much lower coefficient of friction than, say, sandpaper. Since we’re in a
      pretend p5 world, we can arbitrarily set the coefficient based on
      how much friction we want to simulate.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const c = 0.01;</pre
    >

    <a
      data-primary="friction"
      data-secondary="normal force"
      data-type="indexterm"
    ></a>
    <a data-primary="normal force" data-type="indexterm"></a>

    <p>
      Now for the second part: <code>N</code>. <code>N</code> refers to the
      <strong><em>normal force</em></strong
      >, the force perpendicular to the object’s motion along a surface. Think
      of a vehicle driving along a road. The vehicle pushes down against the
      road with gravity, and Newton’s third law tells us that the road in turn
      pushes back against the vehicle. That’s the normal force. The greater the
      gravitational force, the greater the normal force. As we’ll see in the
      next section, gravity is associated with mass, and so a lightweight sports
      car would experience less friction than a massive tractor trailer truck.
      With the diagram above, however, where the object is moving along a
      surface at an angle, computing the magnitude and direction of the normal
      force is a bit more complicated because it doesn’t point in the opposite
      direction of gravity. We’ll need to know something about angles and
      trigonometry.
    </p>

    <p>
      All of these specifics are important; however, in p5, a “good
      enough” simulation can be achieved without them. We can, for example, make
      friction work with the assumption that the normal force will always have a
      magnitude of 1. When we get into trigonometry in the next chapter, we’ll
      remember to return to this question and make our friction example a bit
      more sophisticated. Therefore:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const normal = 1;</pre
    >

    <p>
      Now that we have both the magnitude and direction for friction, we can put
      it all together…
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const c = 0.01;
const normal = 1;
//{!1} Let's figure out the magnitude of friction (really just an arbitrary constant).
const frictionMag = c * normal;

const friction = this.velocity.copy();
friction.mult(-1);
friction.normalize();

// Take the unit vector and multiply it by magnitude and we have our force vector!
friction.mult(frictionMag);</pre
    >

    <p>
      …and add it to our “forces” example, where many objects experience wind,
      gravity, and now friction:
    </p>

    <figure
      class="two-col"
      data-p5-sketch="https://editor.p5js.org/embed/SkUTq1MPQ"
    >
      <img alt="No friction" src="chapter02/ch02_ex04a.png" />
      <figcaption>No friction&nbsp;</figcaption>
    </figure>

    <figure
      class="two-col"
      data-p5-sketch="https://editor.p5js.org/embed/B1isyebug"
    >
      <img alt="With friction" src="chapter02/ch02_ex04b.png" />
      <figcaption>With friction&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 2.4: Including friction</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
function draw() {
  background(255);

  const wind = createVector(0.001, 0);
  //{!1} We could scale by mass to be more accurate.
  const gravity = createVector(0, 0.1);

  for (let i = 0; i < movers.length; i++) {
		//{!5 .bold}
		const c = 0.01;
    const friction = movers[i].velocity.copy();
    friction.mult(-1);
    friction.normalize();
    friction.mult(c);
    //{!1 .bold} Apply the friction force vector to the object.
    movers[i].applyForce(friction);
    movers[i].applyForce(wind);
    movers[i].applyForce(gravity);

    movers[i].update();
    movers[i].display();
    movers[i].checkEdges();
  }
}</pre
    >

    <p>
      Running this example, you’ll notice that the circles don’t even make it to
      the right side of the window. Since friction continuously pushes against
      the object in the opposite direction of its movement, the object
      continuously slows down. This can be a useful technique or a problem
      depending on the goals of your visualization.
    </p>

    <div data-type="exercise" id="chapter02_exercise4">
      <h5>Exercise 2.4</h5>

      <p>
        Create pockets of friction in a p5 sketch so that objects only
        experience friction when crossing over those pockets. What if you vary
        the strength (friction coefficient) of each area? What if you make some
        pockets feature the opposite of friction—i.e., when you enter a given
        pocket you actually speed up instead of slowing down?
      </p>
    </div>
  </section>

  <section data-type="sect1" id="chapter02_section8">
    <h2>2.8 Air and Fluid Resistance</h2>

    <figure id="chapter02_figure4">
      <img alt="Figure 2.4" src="chapter02/ch02_04.png" />
      <figcaption>Figure 2.4</figcaption>
    </figure>

    <a data-primary="drag force" data-type="indexterm"></a>
    <a
      data-primary="fluid resistance"
      data-secondary="modeling"
      data-type="indexterm"
    ></a>
    <a
      data-primary="forces"
      data-secondary="fluid resistance"
      data-type="indexterm"
    ></a>
    <a
      data-primary="natural phenomena"
      data-secondary="fluid resistance"
      data-tertiary="modeling"
      data-type="indexterm"
    ></a>
    <a data-primary="viscous force" data-type="indexterm"></a>

    <p>
      Friction also occurs when a body passes through a liquid or gas. This
      force has many different names, all really meaning the same thing:
      <em>viscous force</em>, <em>drag force</em>, <em>fluid resistance</em>.
      While the result is ultimately the same as our previous friction examples
      (the object slows down), the way in which we calculate a drag force will
      be slightly different. Let’s look at the formula:
    </p>

    <div data-type="equation">F_d = - \frac{1}{2}\rho\nu^2 A C_d\hat{\nu}</div>

    <p>
      Now let’s break this down and see what we really need for an effective
      simulation in p5, making ourselves a much simpler formula in the
      process.
    </p>

    <ul>
      <li>
        <p>
          <span data-type="equation">F_d</span> refers to <em>drag force</em>,
          the vector we ultimately want to compute and pass into our
          <code>applyForce()</code> function.
        </p>
      </li>
      <li>
        <p>
          - 1/2 is a constant: -0.5. This is fairly irrelevant in terms of our
          p5 world, as we will be making up values for other constants
          anyway. However, the fact that it is negative is important, as it
          tells us that the force is in the opposite direction of velocity (just
          as with friction).
        </p>
      </li>
    </ul>

    <a data-primary="rho (ρ)" data-type="indexterm"></a>
    <a
      data-primary="friction"
      data-secondary="rho (ρ)"
      data-type="indexterm"
    ></a>

    <ul>
      <li>
        <p>
          <span data-type="equation">\rho</span> is the Greek letter
          <em>rho</em>, and refers to the density of the liquid, something we
          don’t need to worry about. We can simplify the problem and consider
          this to have a constant value of 1.
        </p>
      </li>
      <li>
        <p>
          <span data-type="equation">v</span> refers to the speed of the object
          moving. OK, we’ve got this one! The object’s speed is the magnitude of
          the velocity vector: <code>velocity.mag()</code>. And
          <span data-type="equation">v^2</span> just means
          <span data-type="equation">v</span> squared or
          <span data-type="equation">v \times v</span>.
        </p>
      </li>
      <li>
        <p>
          <span data-type="equation">A</span> refers to the frontal area of the
          object that is pushing through the liquid (or gas). An aerodynamic
          Lamborghini, for example, will experience less air resistance than a
          boxy Volvo. Nevertheless, for a basic simulation, we can consider our
          object to be spherical and ignore this element.
        </p>
      </li>
      <li>
        <p>
          <span data-type="equation">C_d</span> is the coefficient of drag,
          exactly the same as the coefficient of friction (μ). This is a
          constant we’ll determine based on whether we want the drag force to be
          strong or weak.
        </p>
      </li>
      <li>
        <p>
          <span data-type="equation">\hat{v}</span> Look familiar? It should.
          This refers to the velocity unit vector, i.e.
          <code>velocity.normalize()</code>. Just like with friction, drag is a
          force that points in the opposite direction of velocity.
        </p>
      </li>
    </ul>

    <p>
      Now that we’ve analyzed each of these components and determined what we
      need for a simple simulation, we can reduce our formula to:
    </p>

    <figure id="chapter02_figure5">
      <img
        alt="Figure 2.5: Our simplified drag force formula"
        src="chapter02/ch02_05.png"
      />
      <figcaption>
        Figure 2.5: Our simplified drag force formula&nbsp;
      </figcaption>
    </figure>

    <p>or:</p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const c = 0.1;
const speed = this.velocity.mag();
//{!1} Part 1 of our formula (magnitude): Cd * v2
const dragMagnitude = c * speed * speed;
const drag = this.velocity.copy();
//{!1} Part 2 of our formula (direction): -1 * velocity
drag.mult(-1);
drag.normalize();
// Magnitude and direction together!
drag.mult(dragMagnitude);</pre
    >

    <a
      data-primary="friction"
      data-secondary="applying to an object"
      data-type="indexterm"
    ></a>

    <p>
      Let’s implement this force in our <code>Mover</code> class example with
      one addition. When we wrote our friction example, the force of friction
      was always present. Whenever an object was moving, friction would slow it
      down. Here, let’s introduce an element to the environment—a “liquid” that
      the <code>Mover</code> objects pass through. The
      <code>Liquid</code> object will be a rectangle and will know about its
      position, width, height, and “coefficient of drag”—i.e., is it easy for
      objects to move through it (like air) or difficult (like molasses)? In
      addition, it should include a function to draw itself on the screen (and
      two more functions, which we’ll see in a moment).
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
class Liquid {

  constructor(x_, y_, w_, h_, c_) {
    this.x = x_;
    this.y = y_;
    this.w = w_;
    this.h = h_;
    //{!1} The liquid object includes a variable defining its coefficient of drag.
    this.c = c_;
  }

  void display() {
    noStroke();
    fill(175);
    rect(this.x, this.y, this.w, this.h);
  }

}</pre
    >

    <p>
      The main program will now include a <code>Liquid</code> object reference
      as well as a line of code that initializes that object.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
let liquid;

function setup() {
  //{!1} Initialize a Liquid object.  Note the coefficient is low (0.1), otherwise the object would come to a halt fairly quickly (which may someday be the effect you want).
  liquid = new Liquid(0, height/2, width, height/2, 0.1);
}</pre
    >

    <p>
      Now comes an interesting question: how do we get the
      <code>Mover</code> object to talk to the <code>Liquid</code> object? In
      other words, we want to execute the following:
    </p>

    <p>
      <em>When a mover passes through a liquid it experiences a drag force.</em>
    </p>

    <p>
      …or in object-oriented speak (assuming we are looping through an array of
      <code>Mover</code> objects with index i):
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
// If a Mover is inside a Liquid, apply the drag force.
if (liquid.contains(movers[i])) {
  liquid[i].drag(movers[i]);
}</pre
    >

    <p>
      The above code tells us that we need to add two functions to the
      <code>Liquid</code> class: (1) a function that determines if a
      <code>Mover</code> object is inside the <code>Liquid</code> object, and
      (2) a function that computes and applies a drag force on the
      <code>Mover</code> object.
    </p>

    The first is easy; we can simply use a Boolean expression to determine if
    the position vector rests inside the rectangle defined by the liquid.

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
contains(m) {
  const pos = m.position;
  //{.offset-top} This Boolean expression determines if the PVector position is inside the rectangle defined by the Liquid class.
  return pos.x > x && pos.x < x + w && pos.y > y && pos.y < y + h;
}</pre
    >

    <p>
      The <code>drag()</code> function is a bit more complicated; however, we’ve
      written the code for it already. This is simply an implementation of our
      formula. The drag force is equal to
      <em
        >the coefficient of drag multiplied by the speed of the
        <code>Mover</code> squared in the opposite direction of velocity!</em
      >
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
 drag(m) {
  const speed = m.velocity.mag();
  // The force's magnitude: Cd * v~2~
  const dragMagnitude = c * speed * speed;
  // The force's direction: -1 * velocity
  const drag = m.velocity.copy();
  // Finalize the force: magnitude and direction together.
  drag.setMag(dragMagnitude);
  //{!1} Apply the force.
  m.applyForce(drag);
}</pre
    >

    <p>
      And with these two functions added to the <code>Liquid</code> class, we’re
      ready to put it all together in the main tab:
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/H1DmxeW_g"
    >
      <img alt="ch02 ex05" src="chapter02/ch02_ex05.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 2.5: Fluid Resistance</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
let movers = [];

let liquid;

function setup() {
  createCanvas(360, 640);
  for (let i = 0; i < 10; i++) {
    movers[i] = new Mover(random(0.1, 5), i * 20, 0);
  }
  liquid = new Liquid(0, height/2, width, height/2, 0.1);
}

function draw() {
  background(255);

  liquid.display();

  for (let i = 0; i < movers.length; i++) {
    if (liquid.contains(movers[i])) {
      liquid.drag(movers[i]);
    }

		//{!2} Note that we are scaling gravity according to mass.
    const m = 0.1 * movers[i].mass;
    PVector gravity = new PVector(0, m);
    movers[i].applyForce(gravity);

    movers[i].update();
    movers[i].display();
    movers[i].checkEdges();
  }
}</pre
    >

    <p>
      Running the example, you should notice that we are simulating balls
      falling into water. The objects only slow down when crossing through the
      gray area at the bottom of the window (representing the liquid). You’ll
      also notice that the smaller objects slow down a great deal more than the
      larger objects. Remember Newton’s second law? <code>A</code> =
      <code>F</code> / <code>M</code>. Acceleration equals force
      <em>divided</em> by mass. A massive object will accelerate less. A smaller
      object will accelerate more. In this case, the acceleration we’re talking
      about is the “slowing down” due to drag. The smaller objects will slow
      down at a greater rate than the larger ones.
    </p>

    <div data-type="exercise" id="chapter02_exercise5">
      <h5>Exercise 2.5</h5>

      <p>
        Take a look at our formula for drag again:
        <strong><em>drag force = coefficient * speed * speed</em></strong
        >. The faster an object moves, the greater the drag force against it. In
        fact, an object not moving in water experiences no drag at all. Expand
        the example to drop the balls from different heights. How does this
        affect the drag as they hit the water?
      </p>
    </div>

    <div data-type="exercise" id="chapter02_exercise6">
      <h5>Exercise 2.6</h5>

      <p>
        The formula for drag also included surface area. Can you create a
        simulation of boxes falling into water with a drag force dependent on
        the length of the side hitting the water?
      </p>
    </div>

    <div data-type="exercise" id="chapter02_exercise7">
      <h5>Exercise 2.7</h5>

      <p>
        Fluid resistance does not only work opposite to the velocity vector, but
        also perpendicular to it. This is known as “lift-induced drag” and will
        cause an airplane with an angled wing to rise in altitude. Try creating
        a simulation of lift.
      </p>
    </div>
  </section>

  <section data-type="sect1" id="chapter02_section9">
    <h2>2.9 Gravitational Attraction</h2>

    <a
      data-primary="gravity"
      data-secondary="modeling"
      data-type="indexterm"
    ></a>
    <a
      data-primary="natural phenomena"
      data-secondary="gravity"
      data-type="indexterm"
    ></a>

    <figure class="half-width-right" id="chapter02_figure6">
      <img alt="Figure 2.6" src="chapter02/ch02_06.png" />
      <figcaption>Figure 2.6</figcaption>
    </figure>

    <p>
      Probably the most famous force of all is gravity. We humans on earth think
      of gravity as an apple hitting Isaac Newton on the head. Gravity means
      that stuff falls down. But this is only <em>our</em> experience of
      gravity. In truth, just as the earth pulls the apple towards it due to a
      gravitational force, the apple pulls the earth as well. The thing is, the
      earth is just so freaking big that it overwhelms all the other gravity
      interactions. Every object with mass exerts a gravitational force on every
      other object. And there is a formula for calculating the strengths of
      these forces, as depicted in Figure 2.6.
    </p>

    <p>Let’s examine this formula a bit more closely.</p>

    <a
      data-primary="forces"
      data-secondary="universal gravitational constant"
      data-type="indexterm"
    ></a>
    <a
      data-primary="gravity"
      data-secondary="universal gravitational constant"
      data-type="indexterm"
    ></a>
    <a
      data-primary="universal gravitational constant"
      data-type="indexterm"
    ></a>

    <ul>
      <li>
        <p>
          <code>F</code> refers to the gravitational force, the vector we
          ultimately want to compute and pass into our
          <code>applyForce()</code> function.
        </p>
      </li>
      <li>
        <p>
          <code>G</code> is the <em>universal gravitational constant</em>, which
          in our world equals 6.67428 x 10<sup>-11</sup> meters cubed per
          kilogram per second squared. This is a pretty important number if your
          name is Isaac Newton or Albert Einstein. It’s not an important number
          if you are a p5 programmer. Again, it’s a constant that we can
          use to make the forces in our world weaker or stronger. Just making it
          equal to one and ignoring it isn’t such a terrible choice either.
        </p>
      </li>
      <li>
        <p>
          <code>m<sub>1</sub></code> and <code>m<sub>2</sub></code> are the
          masses of objects 1 and 2. As we saw with Newton’s second law (<span
            data-type="equation"
            >\vec{F} = M \times \vec{A}</span
          >), mass is also something we could choose to ignore. After all,
          shapes drawn on the screen don’t actually have a physical mass.
          However, if we keep these values, we can create more interesting
          simulations in which “bigger” objects exert a stronger gravitational
          force than smaller ones.
        </p>
      </li>
      <li>
        <p>
          <span data-type="equation">\hat{r}</span> refers to the unit vector
          pointing from object 1 to object 2. As we’ll see in a moment, we can
          compute this direction vector by subtracting the position of one
          object from the other.
        </p>
      </li>
      <li>
        <p>
          <span data-type="equation">r^2</span> refers to the distance between
          the two objects squared. Let’s take a moment to think about this a bit
          more. With everything on the top of the formula—<code>G</code>,
          <code>m<sub>1</sub></code
          >, <code>m<sub>2</sub></code
          >—the bigger its value, the stronger the force. Big mass, big force.
          Big <code>G</code>, big force. Now, when we divide by something, we
          have the opposite. The strength of the force is inversely proportional
          to the distance squared. The <em>farther away</em> an object is, the
          <em>weaker</em> the force; the <em>closer</em>, the <em>stronger</em>.
        </p>
      </li>
    </ul>

    <p>
      Hopefully by now the formula makes some sense to us. We’ve looked at a
      diagram and dissected the individual components of the formula. Now it’s
      time to figure out how we translate the math into p5 code. Let’s
      make the following assumptions.
    </p>

    <p>We have two objects, and:</p>

    <a
      data-primary="gravity"
      data-secondary="implementing model of"
      data-type="indexterm"
    ></a>
    <a
      data-primary="natural phenomena"
      data-secondary="gravity"
      data-type="indexterm"
    ></a>

    <ol>
      <li>
        <p>
          Each object has a position: <code>p5.Vector position1</code> and
          <code>p5.Vector position2</code>.
        </p>
      </li>
      <li>
        <p>
          Each object has a mass: <code>mass1</code> and
          <code>mass2</code>.
        </p>
      </li>
      <li>
        <p>
          There is a variable <code>G</code> for the universal
          gravitational constant.
        </p>
      </li>
    </ol>

    <p>
      Given these assumptions, we want to compute <code>p5.Vector force</code>,
      the force of gravity. We’ll do it in two parts. First, we’ll compute the
      direction of the force <span data-type="equation">\hat{r}</span> in the
      formula above. Second, we’ll calculate the strength of the force according
      to the masses and distance.
    </p>

    <figure class="half-width-right" id="chapter02_figure7">
      <img alt="Figure 2.7" src="chapter02/ch02_07.png" />
      <figcaption>Figure 2.7</figcaption>
    </figure>

    <p>
      Remember in <a href="#chapter01_section10">Chapter 1</a>, when we figured
      out how to have an object accelerate towards the mouse? (See Figure 2.7.)
    </p>

    <p>
      A vector is the difference between two points. To make a vector that
      points from the circle to the mouse, we simply subtract one point from
      another:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const dir = p5.Vector.sub(mouse, position);</pre
    >

    <p>
      In our case, the direction of the attraction force that object 1 exerts on
      object 2 is equal to:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const dir = p5.Vector.sub(position1, position2);
dir.normalize();</pre
    >

    <p>
      Don’t forget that since we want a unit vector, a vector that tells us
      about direction only, we’ll need to <em>normalize</em> the vector after
      subtracting the positions.
    </p>

    <p>
      OK, we’ve got the direction of the force. Now we just need to compute the
      magnitude and scale the vector accordingly.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
float m = (G * mass1 * mass2) / (distance * distance);
dir.mult(m);</pre
    >

    <figure class="half-width-right" id="chapter02_figure8">
      <img alt="Figure 2.8" src="chapter02/ch02_08.png" />
      <figcaption>Figure 2.8</figcaption>
    </figure>

    <p>
      The only problem is that we don’t know the distance. <code>G</code>,
      <code>mass1</code>, and <code>mass2</code> were all givens, but we’ll need
      to actually compute distance before the above code will work. Didn’t we
      just make a vector that points all the way from one position to another?
      Wouldn’t the length of that vector be the distance between two objects?
    </p>

    <p>
      Well, if we add just one line of code and grab the magnitude of that
      vector before normalizing it, then we’ll have the distance.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
//{!1} The vector that points from one object to another
const force = p5.Vector.sub(position1, position2);

//{!1} The length (magnitude) of that vector is the distance between the two objects.
const distance = force.mag();

//{!1} Use the formula for gravity to compute the strength of the force.
const m = (G * mass1 * mass2) / (distance * distance);

//{!1} Normalize and scale the force vector to the appropriate magnitude.
force.normalize();
force.mult(m);</pre
    >

    <p>
      Note that I also renamed the <code>p5.Vector</code> “dir” as “force.” After
      all, when we’re finished with the calculations, the
      <code>p5.Vector</code> we started with ends up being the actual force vector
      we wanted all along.
    </p>

    <p>
      Now that we’ve worked out the math and the code for calculating an
      attractive force (emulating gravity), we need to turn our attention to
      applying this technique in the context of an actual p5 sketch. In
      Example 2.1, you may recall how we created a simple
      <code>Mover</code> object—a class with <code>PVector</code> objects for
      position, velocity, and acceleration as well as an
      <code>applyForce()</code> method. Let’s take this exact class and put it
      in a sketch with:
    </p>

    <figure class="half-width-right" id="chapter02_figure9">
      <img alt="Figure 2.9" src="chapter02/ch02_09.png" />
      <figcaption>Figure 2.9</figcaption>
    </figure>

    <ul>
      <li>
        <p>A single <code>Mover</code> object.</p>
      </li>
      <li>
        <p>
          A single <code>Attractor</code> object (a new class that will have a
          fixed position).
        </p>
      </li>
    </ul>

    <p>
      The <code>Mover</code> object will experience a gravitational pull towards
      the <code>Attractor</code> object, as illustrated in Figure 2.9.
    </p>

    <p>
      We can start by making the new <code>Attractor</code> class very
      simple—giving it a position and a mass, along with a function to display
      itself (tying mass to size).
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
class Attractor {
  //{!2} The Attractor is a simple object that doesn’t move. We just need a mass and a position.
  constructor() {
    this.position = createVector(width/2, height/2);
    this.mass = 20;
  }

  display() {
    stroke(0);
    fill(175,200);
    ellipse(this.position.x, this.position.y, this.mass * 2, this.mass * 2);
  }
}</pre
    >

    <p>
      And in our main program, we can add an instance of the
      <code>Attractor</code> class.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
let m;
let a;

function setup() {
  createCanvas(640, 360);
  m = new Mover();
  //{!1} Initialize Attractor object.
  a = new Attractor();
}

function draw() {
  background(255);

  //{!1} Display Attractor object.
  a.display();

  m.update();
  m.display();
}</pre
    >

    <a
      data-primary="object"
      data-secondary="interaction between"
      data-type="indexterm"
    ></a>

    <p>
      This is a good structure: a main program with a <code>Mover</code> and an
      <code>Attractor</code> object, and a class to handle the variables and
      behaviors of movers and attractors. The last piece of the puzzle is how to
      get one object to attract the other. How do we get these two objects to
      talk to each other?
    </p>

    <p>
      There are a number of ways we could do this. Here are just a few
      possibilities.
    </p>

    <table class="codewide">
      <tbody>
        <tr>
          <th>Task</th>
          <th>Function</th>
        </tr>
        <tr>
          <td>1. A function that receives both an Attractor and a Mover:</td>
          <td>
            <pre>attraction(a,m);</pre>
          </td>
        </tr>
        <tr>
          <td>2. A function in the Attractor class that receives a Mover:</td>
          <td>
            <pre>a.attract(m);</pre>
          </td>
        </tr>
        <tr>
          <td>3. A function in the Mover class that receives an Attractor:</td>
          <td>
            <pre>m.attractedTo(a);</pre>
          </td>
        </tr>
        <tr>
          <td>
            4. A function in the Attractor class that receives a Mover and
            returns a p5.Vector, which is the attraction force. That attraction
            force is then passed into the Mover's applyForce() function:
          </td>
          <td>
            <pre>
const f = a.attract(m);
m.applyForce(f);
</pre
            >
          </td>
        </tr>
      </tbody>
    </table>

    <p>and so on. . .</p>

    <p>
      It’s good to look at a range of options for making objects talk to each
      other, and you could probably make arguments for each of the above
      possibilities. I’d like to at least discard the first one, since an
      object-oriented approach is really a much better choice over an arbitrary
      function not tied to either the <code>Mover</code> or
      <code>Attractor</code> class. Whether you pick option 2 or option 3 is the
      difference between saying “The attractor attracts the mover” or “The mover
      is attracted to the attractor.” Number 4 is really my favorite, at least
      in terms of where we are in this book. After all, we spent a lot of time
      working out the <code>applyForce()</code> function, and I think our
      examples will be clearer if we continue with the same methodology.
    </p>

    <p>In other words, where we once had:</p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
// Made-up force
const f = createVector(0.1, 0);
m.applyForce(f);</pre
    >

    <p>We now have:</p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
//{!1 .bold} Attraction force between two objects
const f = a.attract(m);
m.applyForce(f);</pre
    >

    <p>And so our <code>draw()</code> function can now be written as:</p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
function draw() {
  background(255);

  //{!2 .bold} Calculate attraction force and apply it.
  const f = a.attract(m);
  m.applyForce(f);

  m.update();

  a.display();
  m.display();
}</pre
    >

    <p>
      We’re almost there. Since we decided to put the
      <code>attract()</code> function inside of the
      <code>Attractor</code> class, we’ll need to actually write that function.
      The function needs to receive a <code>Mover</code> object and return a
      <code>PVector</code>, i.e.:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
attract(m) {

}</pre
    >

    <p>
      And what goes inside that function? All of that nice math we worked out
      for gravitational attraction!
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
attract(m) {
  //{!1} What's the force's direction?
  const force = p5.Vector.sub(this.position, m.position);
  const distance = force.mag();
  force.normalize();
  //{!2} What's the force's magnitude?
  float strength = (this.G * this.mass * m.mass) / (distance * distance);
  force.mult(strength);

  //{!1} Return the force so that it can be applied!
  return force;
}</pre
    >

    <a
      data-primary="gravity"
      data-secondary="placing limits on model of"
      data-type="indexterm"
    ></a>

    <p>
      And we’re done. Sort of. Almost. There’s one small kink we need to work
      out. Let’s look at the above code again. See that symbol for divide, the
      slash? Whenever we have one of these, we need to ask ourselves the
      question: What would happen if the distance happened to be a really,
      really small number or (even worse!) zero??! Well, we know we can’t divide
      a number by 0, and if we were to divide a number by something like 0.0001,
      that is the equivalent of multiplying that number by 10,000! Yes, this is
      the real-world formula for the strength of gravity, but we don’t live in
      the real world. We live in the <em>p5</em> world. And in the
      p5 world, the mover could end up being very, very close to the
      attractor and the force could become so strong the mover would just fly
      way off the screen. And so with this formula, it’s good for us to be
      practical and constrain the range of what <code>distance</code> can
      actually be. Maybe, no matter where the <code>Mover</code> actually is, we
      should never consider it less than 5 pixels or more than 25 pixels away
      from the attractor.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
  distance = constrain(distance,5,25);</pre
    >

    <p>
      For the same reason that we need to constrain the minimum distance, it’s
      useful for us to do the same with the maximum. After all, if the mover
      were to be, say, 500 pixels from the attractor (not unreasonable), we’d be
      dividing the force by 250,000. That force might end up being so weak that
      it’s almost as if we’re not applying it at all.
    </p>

    <p>
      Now, it’s really up to you to decide what behaviors you want. But in the
      case of, “I want reasonable-looking attraction that is never absurdly weak
      or strong,” then constraining the distance is a good technique.
    </p>

    <p>
      Our <code>Mover</code> class hasn’t changed at all, so let’s just look at
      the main program and the <code>Attractor</code> class as a whole, adding a
      variable <code>G</code> for the universal gravitational constant. (On the
      website, you’ll find that this example also has code that allows you to
      move the <code>Attractor</code> object with the mouse.)
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/HyWqel-de"
    >
      <img alt="ch02 ex06" src="chapter02/ch02_ex06.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 2.6: Attraction</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
//{!2} A Mover and an Attractor
let m;
let a;

function setup() {
  size(640, 360);
  m = new Mover();
  a = new Attractor();
}

function draw() {
  background(255);

  //{!2} Apply the attraction force from the Attractor on the Mover.
  const force = a.attract(m);
  m.applyForce(force);
  m.update();

  a.display();
  m.display();
}

class Attractor {

  constructor() {
    this.position = createVector(width/2, height/2);
    this.mass = 20;
    this.G = 0.4;
  }

  attract(m) {
    const force = p5.Vector.sub(position,m.position);
    const distance = force.mag();
    //{!1} Remember, we need to constrain the distance so that our circle doesn't spin out of control.
    distance = constrain(distance, 5.0, 25.0);
    force.normalize();
    const strength = (this.G * this.mass * m.mass) / (distance * distance);
    force.mult(strength);
    return force;
  }

  display() {
    stroke(0);
    fill(175,200);
    ellipse(this.position.x, this.position.y, this.mass * 2, this.mass * 2);
  }
}</pre
    >

    <p>
      And we could, of course, expand this example using an array to include
      many <code>Mover</code> objects, just as we did with friction and drag:
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/rJ9l-x-Ox"
    >
      <img alt="ch02 ex07" src="chapter02/ch02_ex07.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 2.7: Attraction with many Movers</h5>
    </div>

    <pre data-code-language="java" data-type="programlisting" class="codesplit">
//{!1} Now we have 10 Movers!
const movers = [];

let a;

function setup() {
  size(400, 400);
  for (let i = 0; i < 10; i++) {
    //{!1 .offset-top} Each Mover is initialized randomly.
    movers[i] = new Mover(random(0.1, 2), random(width), random(height));
  }
  a = new Attractor();
}

function draw() {
  background(255);

  a.display();

  for (let i = 0; i < movers.length; i++) {
    //{!1} Calculate an attraction force for each Mover object.
    const force = a.attract(movers[i]);
    movers[i].applyForce(force);

    movers[i].update();
    movers[i].display();
  }

}</pre
    >

    <div data-type="exercise" id="chapter02_exercise8">
      <h5>Exercise 2.8</h5>

      <p>
        In the example above, we have a system (i.e. array) of
        <code>Mover</code> objects and one <code>Attractor</code> object. Build
        an example that has systems of both movers and attractors. What if you
        make the attractors invisible? Can you create a pattern/design from the
        trails of objects moving around attractors? See the
        <a href="http://processing.org/exhibition/works/metropop/"
          >Metropop Denim project by Clayton Cubitt and Tom Carden</a
        >
        for an example.
      </p>
    </div>

    <div data-type="exercise" id="chapter02_exercise9">
      <h5>Exercise 2.9</h5>

      <p>
        It’s worth noting that gravitational attraction is a model we can follow
        to develop our own forces. This chapter isn’t suggesting that you should
        exclusively create sketches that use gravitational attraction. Rather,
        you should be thinking creatively about how to design your own rules to
        drive the behavior of objects. For example, what happens if you design a
        force that is weaker the closer it gets and stronger the farther it
        gets? Or what if you design your attractor to attract faraway objects,
        but repel close ones?
      </p>
    </div>
  </section>

  <section data-type="sect1" id="chapter02_section10">
    <h2>2.10 Everything Attracts (or Repels) Everything</h2>

    <p>
      Hopefully, you found it helpful that we started with a simple scenario—<em
        >one object attracts another object</em
      ><code>—</code>and moved on to <em>one object attracts many objects</em>.
      However, it’s likely that you are going to find yourself in a slightly
      more complex situation: <em>many objects attract each other</em>. In other
      words, every object in a given system attracts every other object in that
      system (except for itself).
    </p>

    <p>
      We’ve really done almost all of the work for this already. Let’s consider
      a p5 sketch with an array of <code>Mover</code> objects:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const movers = [];

function setup() {
  createCanvas(400, 400);
  for (let i = 0; i < 10; i++) {
    movers[i] = new Mover(random(0.1, 2), random(width), random(height));
  }
}

function draw() {
  background(255);
  for (let i = 0; i < movers.length; i++) {
    movers[i].update();
    movers[i].display();
  }
}</pre
    >

    <p>
      The <code>draw()</code> function is where we need to work some magic.
      Currently, we’re saying: “for every mover <code>i</code>, update and
      display yourself.” Now what we need to say is: “for every mover
      <code>i</code>, be attracted to every other mover <code>j</code>, and
      update and display yourself.”
    </p>

    <p>To do this, we need to nest a second loop.</p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
 for (let i = 0; i < movers.length; i++) {
    //{!1} For every Mover, check every Mover!
    for (let j = 0; j < movers.length; j++) {
      const force = movers[j].attract(movers[i]);
      movers[i].applyForce(force);
    }
    movers[i].update();
    movers[i].display();
  }</pre
    >

    <p>
      In the previous example, we had an <code>Attractor</code> object with a
      function named <code>attract()</code>. Now, since we have movers
      attracting movers, all we need to do is copy the
      <code>attract()</code> function into the <code>Mover</code> class.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
class Mover {

  //[inline] All the other stuff we had before plus. . .

  //{!1} The Mover now knows how to attract another Mover.
  attract(m) {

    const force = p5.Vector.sub(this.position,m.position);
    const distance = force.mag();
    distance = constrain(distance,5.0,25.0);
    force.normalize();

    // note to add a value for gravity in your Mover class, this.G
    float strength = (this.G * this.mass * m.mass) / (distance * distance);
    force.mult(strength);
    return force;
  }
}</pre
    >

    <p>
      Of course, there’s one small problem. When we are looking at every mover
      <code>i</code> and every mover <code>j</code>, are we OK with the times
      that <code>i</code> equals <code>j</code>? For example, should mover #3
      attract mover #3? The answer, of course, is no. If there are five objects,
      we only want mover #3 to attract 0, 1, 2, and 4, skipping itself. And so,
      we finish this example by adding a simple conditional statement to skip
      applying the force when i equals j.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/SkYSWlb_x"
    >
      <img alt="ch02 ex08" src="chapter02/ch02_ex08.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 2.8: Mutual attraction</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const movers = [];

function setup() {
  createCanvas(400, 400);
  for (let i = 0; i < 20; i++) {
    movers[i] = new Mover(random(0.1, 2), random(width), random(height));
  }
}

function draw() {
  background(255);

  for (let i = 0; i < movers.length; i++) {
    for (let j = 0; j < movers.length; j++) {
      //{!1} Don't attract yourself!
      if (i != j) {
        const force = movers[j].attract(movers[i]);
        movers[i].applyForce(force);
      }
    }
    movers[i].update();
    movers[i].display();
  }
}</pre
    >

    <div data-type="exercise" id="chapter02_exercise10">
      <h5>Exercise 2.10</h5>

      <p>
        Change the attraction force in Example 2.8 to a repulsion force. Can you
        create an example in which all of the <code>Mover</code> objects are
        attracted to the mouse, but repel each other? Think about how you need
        to balance the relative strength of the forces and how to most
        effectively use distance in your force calculations.
      </p>
    </div>

    <div data-type="tip">
      <h2>The Ecosystem Project</h2>

      <p>Step 2 Exercise:</p>

      <p>
        Incorporate the concept of forces into your ecosystem. Try introducing
        other elements into the environment (food, a predator) for the creature
        to interact with. Does the creature experience attraction or repulsion
        to things in its world? Can you think more abstractly and design forces
        based on the creature’s desires or goals?
      </p>
    </div>
  </section>
</section>
